import { Component, Input, Output, EventEmitter, ViewChild, TemplateRef, OnInit } from '@angular/core';
import { NotifyService } from '@farris/ui-notify';
import { DomService } from '@farris/designer-services';
import { ExpressionEditorComponent } from '../expression-editor/expression-editor.component';

/**
 * 属性编辑器，目前用于列表列的可见、只读、必填属性，包含布尔、自定义函数、表达式三个选项
 */
@Component({
  selector: 'app-javascript-boolean-template-editor',
  templateUrl: './javascript-boolean-editor.component.html',
  styleUrls: ['./javascript-boolean-editor.component.css']
})
export class JavaScriptBooleanEditorComponent implements OnInit {
  @Output() closeModal = new EventEmitter<any>();
  @Output() submitModal = new EventEmitter<any>();
  @Input() value: any;
  @Input() editorParams: JSBooleanExpEditorParams;
  @ViewChild('bindingFooter') modalFooter: TemplateRef<any>;

  get modalConfig() {
    return {
      title: this.editorParams.modalTitle || '编辑器',
      width: 1060,
      height: 700,
      showButtons: true
    };
  }
  /** 取值的枚举项配置 */
  radioOptions = [];

  /** 取值类型：true/false/自定义函数/表达式 */
  radioValue: string;

  /** 自定义函数值 */
  customValue = '';

  /** 代码编辑器配置项 */
  codeEditorOptions = {
    theme: 'vs-dark',
    language: 'javascript',
    formatOnType: true,
    foldingStrategy: 'indentation',      // 显示缩进
    folding: true,                       // 启用代码折叠功能
    showFoldingControls: 'always',       // 默认显示装订线
    automaticLayout: true                // 监测父容器变化
  };

  /** 代码编辑器实例 */
  monacoEditor;

  /** 表达式编辑器参数配置 */
  expressionParams: any = {};

  /** 表达式值 */
  expressionValue = '';

  /** 表达式编辑器实例 */
  @ViewChild(ExpressionEditorComponent) expressionEditorComponent: ExpressionEditorComponent;

  constructor(private domService: DomService, private notifyService: NotifyService) { }

  ngOnInit() {
    this.assembleRadioOptions();
    this.initExpression();
    if (this.value === null || this.value === undefined) {
      this.radioValue = null;
      return;
    }
    switch (typeof (this.value)) {
      case 'boolean': {
        // 值为布尔值，则认为true或false
        this.radioValue = this.value ? 'true' : 'false';
        break;
      }
      case 'string': {
        // 值为字符串，则认为是自定义函数
        this.radioValue = 'custom';
        this.customValue = this.value;
        break;
      }
      case 'object': {
        // 值为对象，则认为是表达式
        this.radioValue = 'expression';
        break;
      }
    }

  }
  onMonacoInit($event) {
    this.monacoEditor = $event.editor;
  }
  /**
   * 单选框枚举值
   */
  private assembleRadioOptions() {
    this.radioOptions = [
      { value: 'true', text: '是' },
      { value: 'false', text: '否' }
    ];
    if (this.editorParams.showJavascript) {
      this.radioOptions.push(
        { value: 'custom', text: '自定义函数' }
      );
    }
    if (this.editorParams.showExpression) {
      this.radioOptions.push(
        { value: 'expression', text: '表达式' }
      );
    }
  }

  changeRadioType() {
    // 离开表达式界面时，保存当前填写的表达式值
    if (this.editorParams.showExpression && this.radioValue !== 'expression' && this.expressionEditorComponent) {
      // this.expressionValue = this.expressionEditorComponent.expEditor.getExpr() || '';
    }
  }
  /**
   * 确定
   */
  clickConfirm() {
    this.clearOriginalExpression();


    if (this.radioValue === null || this.radioValue === undefined) {
      this.submitModal.emit({ value: null });
      return;
    }
    switch (this.radioValue) {
      case 'true': {
        this.submitModal.emit({ value: true }); break;
      }
      case 'false': {
        this.submitModal.emit({ value: false }); break;
      }
      case 'custom': {
        this.submitModal.emit({ value: this.customValue }); break;
      }
      case 'expression': {
        const expressionId = this.setExpression();
        if (!expressionId) {
          return;
        }
        this.submitModal.emit({
          value: {
            type: 'Expression',
            expressionId
          }
        });
      }
    }
  }

  /**
   * 取消
   */
  clickCancel() {
    this.closeModal.emit();
  }
  /**
   * 初始化表达式相关配置
   */
  private initExpression() {
    if (!this.editorParams.showExpression) {
      this.radioValue = null;
      return;
    }

    this.expressionParams = {
      fieldId: this.editorParams.bindingFieldId,
      viewModelId: this.editorParams.viewModelId,
      expType: this.editorParams.expressionType
    };
    // 必填表达式需要配置提示消息
    if (this.editorParams.expressionType === 'require') {
      this.expressionParams.message = '';
    }
    if (!this.value || !this.value.expressionId || !this.editorParams.bindingFieldId) {
      return;
    }

    const expField = this.domService.expressions.find(e => e.fieldId === this.editorParams.bindingFieldId);
    if (!expField) {
      return;
    }
    const originalExpConfig = expField.expression.find(exp => exp.id === this.value.expressionId);
    this.expressionValue = originalExpConfig && originalExpConfig.value;

    if (this.editorParams.expressionType === 'require') {
      this.expressionParams.message = originalExpConfig.message;
    }
  }


  /**
   * 保存表达式
   */
  private setExpression() {
    // const newExpr = this.expressionEditorComponent.expEditor.getExpr() || '';
    // if (!newExpr) {
    //   this.notifyService.warning('请先配置表达式');
    //   return;
    // }
    // return this.expressionEditorComponent.saveExpression(newExpr);
    return this.expressionEditorComponent.saveExpression('');
  }
  /**
   * 清除原表达式
   */
  private clearOriginalExpression() {
    if (this.value && this.value.type === 'Expression' && this.radioValue !== 'expression') {
      const exp = this.domService.expressions.find(e => e.fieldId === this.editorParams.bindingFieldId);
      if (!exp || !exp.expression) {
        return;
      }

      exp.expression = exp.expression.filter(e => e.type !== this.editorParams.expressionType);
    }
  }



}

class JSBooleanExpEditorParams {
  /** 弹窗标题 */
  public modalTitle?: string;

  public viewModelId: string;

  /** 是否支持表达式配置项，默认false */
  public showExpression?= false;

  /** 当前控件绑定的字段或变量的ID ，在支持表达式配置时，必填 */
  public bindingFieldId?: string;

  /** 表达式类型 ，在支持表达式配置时，必填 */
  public expressionType?: string;

  /** 是否支持自定义函数配置项，默认false */
  public showJavascript?= false;

  /** 自定义函数示例代码 */
  public exampleCode: string;
}
